﻿using System;
using System.Runtime.InteropServices;
using UnityEngine;

[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class OpenDialogFile {
    public int structSize = 0;
    public IntPtr dlgOwner = IntPtr.Zero;
    public IntPtr instance = IntPtr.Zero;
    public String filter = null;
    public String customFilter = null;
    public int maxCustFilter = 0;
    public int filterIndex = 0;
    public String file = null;
    public int maxFile = 0;
    public String fileTitle = null;
    public int maxFileTitle = 0;
    public String initialDir = null;
    public String title = null;
    public int flags = 0;
    public short fileOffset = 0;
    public short fileExtension = 0;
    public String defExt = null;
    public IntPtr custData = IntPtr.Zero;
    public IntPtr hook = IntPtr.Zero;
    public String templateName = null;
    public IntPtr reservedPtr = IntPtr.Zero;
    public int reservedInt = 0;
    public int flagsEx = 0;
}

[StructLayout (LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class OpenDialogDir {
    public IntPtr hwndOwner = IntPtr.Zero;
    public IntPtr pidlRoot = IntPtr.Zero;
    public String pszDisplayName = null;
    public String lpszTitle = null;
    public UInt32 ulFlags = 0;
    public IntPtr lpfn = IntPtr.Zero;
    public IntPtr lParam = IntPtr.Zero;
    public int iImage = 0;
}

public class DllOpenFileDialog {
    [DllImport ("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
    public static extern bool GetOpenFileName ([In, Out] OpenDialogFile ofn);

    [DllImport ("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
    public static extern bool GetSaveFileName ([In, Out] OpenDialogFile ofn);

    [DllImport ("shell32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
    public static extern IntPtr SHBrowseForFolder ([In, Out] OpenDialogDir ofn);

    [DllImport ("shell32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
    public static extern bool SHGetPathFromIDList ([In] IntPtr pidl, [In, Out] char[] fileName);

}

public class FileDialog {

    const int BIF_NEWDIALOGSTYLE = 0x00000040;
    const int BIF_EDITBOX = 0x00000010;
    const int BIF_DONTGOBELOWDOMAIN = 0x00000002;
    const int BIF_STATUSTEXT = 0x00000004;
    const int BIF_RETURNFSANCESTORS = 0x00000008;
    const int BIF_BROWSEINCLUDEURLS = 0x00000080;
    const int BIF_BROWSEINCLUDEFILES = 0x00004000;
    const int BIF_BROWSEFILEJUNCTIONS = 0x00010000;

    public static string GetDialogDir () {
        OpenDialogDir ofn2 = new OpenDialogDir ();
        ofn2.pszDisplayName = new string (new char[2000]);; // 存放目录路径缓冲区  
        ofn2.lpszTitle = "打开资源文件夹"; // 标题  
        ofn2.ulFlags = BIF_NEWDIALOGSTYLE; // 新的样式,带编辑框  
        IntPtr pidlPtr = DllOpenFileDialog.SHBrowseForFolder (ofn2);

        char[] charArray = new char[2000];
        for (int i = 0; i < 2000; i++)
            charArray[i] = '\0';

        DllOpenFileDialog.SHGetPathFromIDList (pidlPtr, charArray);
        string fullDirPath = new String (charArray);
        fullDirPath = fullDirPath.Substring (0, fullDirPath.IndexOf ('\0'));

        Debug.Log (fullDirPath); //这个就是选择的目录路径。
        return fullDirPath;
    }

    public static string GetOpenFileName (string filter, string title, string defaultDir) {
        OpenDialogFile pth = new OpenDialogFile();
        pth.structSize = System.Runtime.InteropServices.Marshal.SizeOf(pth);
        pth.filter = filter;
        pth.file = new string(new char[256]);
        pth.maxFile = pth.file.Length;
        pth.fileTitle = new string(new char[64]);
        pth.maxFileTitle = pth.fileTitle.Length;
        pth.initialDir = defaultDir;  // default path  
        pth.title = title;
        pth.defExt = "*";
        pth.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008;
        //0x00080000   是否使用新版文件选择窗口
        //0x00000200   是否可以多选文件
        if (DllOpenFileDialog.GetOpenFileName(pth))
        {
            string filepath = pth.file;//选择的文件路径;  
            Debug.Log(filepath);
            return filepath;
        }

        return null;
    }
}